{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "nbsphinx": "hidden"
   },
   "source": [
    "This notebook is part of the `clifford` documentation: https://clifford.readthedocs.io/."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Object Oriented CGA "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " This is a shelled out demo for a object-oriented approach to CGA with `clifford`.  The `CGA` object holds the original layout for an arbitrary geometric algebra , and the conformalized version. It provides up/down projections, as well as easy ways to generate objects and operators. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Quick Use Demo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from clifford.cga import CGA, Round, Translation\n",
    "from clifford import Cl\n",
    "\n",
    "g3,blades = Cl(3)   \n",
    "\n",
    "cga = CGA(g3)  # make cga from existing ga\n",
    "# or \n",
    "cga = CGA(3)   # generate cga from dimension of 'base space'\n",
    "\n",
    "locals().update(cga.blades)        # put ga's blades in local namespace\n",
    "\n",
    "C = cga.round(e1,e2,e3,-e2)      # generate unit sphere from points \n",
    "C                           "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Objects \n",
    "cga.round()              # from None \n",
    "cga.round(3)             # from dim of space\n",
    "cga.round(e1,e2,e3,-e2)  # from points\n",
    "cga.round(e1,e2,e3)      # from points\n",
    "cga.round(e1,e2)         # from points\n",
    "cga.round((e1,3))        # from center, radius\n",
    "cga.round(cga.round().mv)# from existing multivector\n",
    "\n",
    "cga.flat()               # from None \n",
    "cga.flat(2)              # from dim of space\n",
    "cga.flat(e1,e2)          # from points\n",
    "cga.flat(cga.flat().mv)  # from existing multivector\n",
    "\n",
    "\n",
    "## Operations\n",
    "cga.dilation()          # from from None \n",
    "cga.dilation(.4)        # from int\n",
    " \n",
    "cga.translation()       # from None \n",
    "cga.translation(e1+e2)  # from vector  \n",
    "cga.translation(cga.down(cga.null_vector()))\n",
    "\n",
    "cga.rotation()          # from None\n",
    "cga.rotation(e12+e23)   # from bivector \n",
    "\n",
    "cga.transversion(e1+e2).mv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cga.round().inverted()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "D = cga.dilation(5)\n",
    "cga.down(D(e1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "C.mv # any CGA object/operator has a multivector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "C.center_down,C.radius # some properties of spheres"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "T = cga.translation(e1+e2) # make a translation \n",
    "C_ = T(C)                  # translate the sphere \n",
    "cga.down(C_.center)        # compute center again"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cga.round()       #  no args == random sphere \n",
    "cga.translation() #             random translation "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if 1 in map(int, [1,2]):\n",
    "    print(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Objects "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Vectors "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "code_folding": []
   },
   "outputs": [],
   "source": [
    "a = cga.base_vector()  # random vector with components in base space only\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cga.up(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cga.null_vector()  # create null vector directly"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Sphere (point pair, circles)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "C = cga.round(e1, e2, -e1, e3) # generates sphere from points\n",
    "C = cga.round(e1, e2, -e1)     # generates circle from points\n",
    "C = cga.round(e1, e2)          # generates point-pair from points\n",
    "#or \n",
    "C2 = cga.round(2)            # random 2-sphere  (sphere)\n",
    "C1 = cga.round(1)            # random 1-sphere, (circle)\n",
    "C0 = cga.round(0)            # random 0-sphere, (point pair)\n",
    "\n",
    "\n",
    "C1.mv                        # access the multivector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "C = cga.round(e1, e2, -e1, e3)\n",
    "C.center,C.radius        # spheres have properties"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cga.down(C.center) == C.center_down "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "C_ = cga.round().from_center_radius(C.center,C.radius)\n",
    "C_.center,C_.radius"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Operators"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "T = cga.translation(e1) # generate translation \n",
    "T.mv "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "C = cga.round(e1, e2, -e1) \n",
    "T.mv*C.mv*~T.mv         # translate a sphere "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "T(C)                # shorthand call, same as above. returns type of arg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "T(C).center   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": "block",
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
